import pygame
import numpy as np
from building import Building
from terrain import Terrain
from ui.building_menu import BuildingMenu
from ui.building_list import BuildingList

class Game:
    def __init__(self, screen):
        self.screen = screen
        self.terrain = Terrain(20, 20)  # 20x20的地形网格
        self.buildings = []
        self.selected_building_type = None
        self.building_preview = None
        self.dragging = False
        self.drag_start_pos = None
        
        # 获取屏幕尺寸
        screen_width = screen.get_width()
        screen_height = screen.get_height()
        menu_width = 200  # 菜单宽度
        
        # 创建建筑菜单（右侧）
        self.building_menu = BuildingMenu(screen_width - menu_width, 0, menu_width, screen_height)
        
        # 创建建筑列表（左侧）
        self.building_list = BuildingList(0, 0, menu_width, screen_height)
        
        # 资源
        self.minerals = 10000000
        self.supply = 10
        self.max_supply = 20
    
    def handle_event(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:  # 左键点击
                if self.building_menu.rect.collidepoint(event.pos):
                    # 从菜单选择建筑
                    building_type = self.building_menu.handle_event(event)
                    if building_type and self.minerals >= self.building_menu.building_types[building_type]['cost']:
                        self.selected_building_type = building_type
                        self.dragging = True
                        self.drag_start_pos = event.pos
                        # 立即创建预览
                        self.update_building_preview(event.pos)
                else:
                    # 放置建筑
                    self.place_building(event.pos)
            elif event.button == 3:  # 右键点击
                self.cancel_building_placement()
        
        elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1 and self.dragging:
                self.dragging = False
                if not self.building_menu.rect.collidepoint(event.pos):
                    self.place_building(event.pos)
                self.selected_building_type = None
                self.building_preview = None
        
        elif event.type == pygame.MOUSEMOTION:
            if self.dragging or self.selected_building_type:
                self.update_building_preview(event.pos)
    
    def check_position_valid(self, grid_x, grid_y, width, height):
        # 检查是否超出地图边界
        if (grid_x < 0 or grid_y < 0 or 
            grid_x + width > self.terrain.width or 
            grid_y + height > self.terrain.height):
            return False
        
        # 创建临时建筑用于碰撞检测
        temp_building = Building(grid_x, grid_y, width, height, (0, 0, 0))
        
        # 检查是否与其他建筑重叠
        for building in self.buildings:
            if building.overlaps(temp_building):
                return False
        
        return True
    
    def check_grid_valid(self, grid_x, grid_y):
        # 检查单个格子是否有效
        if (grid_x < 0 or grid_y < 0 or 
            grid_x >= self.terrain.width or 
            grid_y >= self.terrain.height):
            return False
        
        # 检查是否与其他建筑重叠
        for building in self.buildings:
            if (grid_x >= building.grid_x and grid_x < building.grid_x + building.width and
                grid_y >= building.grid_y and grid_y < building.grid_y + building.height):
                return False
        
        return True
    
    def update_building_preview(self, pos):
        if self.selected_building_type:
            grid_pos = self.terrain.screen_to_grid(pos)
            if grid_pos:
                building_type = self.building_menu.building_types[self.selected_building_type]
                self.building_preview = Building(
                    grid_pos[0], grid_pos[1],
                    building_type['size'][0], building_type['size'][1],
                    building_type['color']
                )
                
                # 检查每个格子的有效性
                for x in range(building_type['size'][0]):
                    for y in range(building_type['size'][1]):
                        grid_key = (x, y)
                        self.building_preview.grid_valid[grid_key] = self.check_grid_valid(
                            grid_pos[0] + x,
                            grid_pos[1] + y
                        )
                
                # 检查整体位置是否有效
                self.building_preview.is_valid = self.check_position_valid(
                    grid_pos[0], grid_pos[1],
                    building_type['size'][0], building_type['size'][1]
                )
            else:
                # 如果不在有效网格内，也创建预览但标记为无效
                building_type = self.building_menu.building_types[self.selected_building_type]
                self.building_preview = Building(
                    0, 0,  # 使用任意位置，因为会立即被标记为无效
                    building_type['size'][0], building_type['size'][1],
                    building_type['color']
                )
                self.building_preview.is_valid = False
                # 所有格子都标记为无效
                for x in range(building_type['size'][0]):
                    for y in range(building_type['size'][1]):
                        self.building_preview.grid_valid[(x, y)] = False
    
    def update(self):
        # 获取当前鼠标位置
        mouse_pos = pygame.mouse.get_pos()
        
        # 如果选择了建筑类型，就更新预览
        if self.selected_building_type:
            # 如果鼠标不在菜单区域内，更新预览
            if not self.building_menu.rect.collidepoint(mouse_pos):
                self.update_building_preview(mouse_pos)
    
    def draw(self):
        self.screen.fill((0, 0, 0))
        self.terrain.draw(self.screen)
        
        # 绘制已放置的建筑
        for building in self.buildings:
            building.draw(self.screen, self.terrain)
        
        # 绘制建筑预览
        if self.building_preview:
            self.building_preview.draw(self.screen, self.terrain, is_preview=True)
        
        # 绘制菜单
        self.building_menu.draw(self.screen, self.minerals)
    
    def place_building(self, pos):
        if not self.selected_building_type:
            return
        
        grid_pos = self.terrain.screen_to_grid(pos)
        if not grid_pos:
            return
        
        building_type = self.building_menu.building_types[self.selected_building_type]
        if self.minerals < building_type['cost']:
            return
        
        # 检查位置是否有效
        if not self.check_position_valid(
            grid_pos[0], grid_pos[1],
            building_type['size'][0], building_type['size'][1]
        ):
            return
        
        new_building = Building(
            grid_pos[0], grid_pos[1],
            building_type['size'][0], building_type['size'][1],
            building_type['color']
        )
        
        self.buildings.append(new_building)
        self.minerals -= building_type['cost']
        self.selected_building_type = None
        self.building_preview = None
    
    def cancel_building_placement(self):
        self.selected_building_type = None
        self.building_preview = None
        self.dragging = False